#pragma once

#define DBG

#ifdef DBG

#include <cstdio>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <string>
#include <cstdio>
#include <ctime>
#include <cstdarg>
#include <cstring>

#include <cstdlib>
#include <cassert>

enum LogLevel
{
    DEBUG = 0,
    NORMAL,
    WARNING,
    ERROR,
    FATAL
};


const char* to_level(LogLevel level)
{
    switch (level)
    {
        case DEBUG:
            return "DEBUG";
        case NORMAL:
            return "NORMAL";
        case WARNING:
            return "WARNING";
        case ERROR:
            return "ERROR";
        case FATAL:
            return "FATAL";
        default:
            return nullptr;
    }
}

// [日记等级] [时间] [线程ID] [%s:%d], [message]
void logMessage(LogLevel level, const std::string& message, const std::string& filepath, const uint32_t line, ...)
{
    const static int NUM = 1024;

    std::time_t now = std::time(nullptr);
    std::tm* localtime = std::localtime(&now);
    char timeStr[20];
    std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", localtime);

    char logfix[NUM];
    snprintf(logfix, sizeof(logfix), "[%s][%s][%p][%s:%d] ", to_level(level), timeStr, pthread_self(),filepath.c_str(), line);

    char logcontect[NUM];
    va_list arg;
    va_start(arg, line);
    vsnprintf(logcontect, sizeof(logcontect), message.c_str(), arg);

    std::cout << logfix << logcontect << std::endl;

}

#define LOG(level, message, ...) do { logMessage(level, message, __FILE__, __LINE__, ##__VA_ARGS__); } while(0)

#endif // DBG